<template>
  <BasicModal
    v-bind="$attrs"
    @register="registerModal"
    :title="title ? `${title} - ${FormModeEntityRef.Display}` : FormModeEntityRef.Display"
    @ok="handleOk"
    @keypress.enter="handleOk"
  >
    <BasicForm @register="registerForm" />
  </BasicModal>

  <MaterialSelectDrawer @register="registerMaterialSelect" :callBackFunc="chooseMaterial" />
</template>

<script lang="ts">
  import { defineComponent, ref, PropType, unref, h } from 'vue';
  import { BasicModal, useModalInner } from '@/components/Modal';
  import { BasicForm, useForm, FormSchema } from '@/components/Form';
  import { useI18n } from '@/hooks/web/useI18n';
  import { useMessage } from '@/hooks/web/useMessage';

  import { isFunction, isArray, isObject, isNullOrUnDef, isNullAndUnDef } from '@/utils/is';
  import { propTypes } from '@/utils/propTypes';

  import { FormModeEnum, FormModeEntity } from '@/enums/formEnum';

  import type { AdFetchParams } from '@/components/AdTable/src/types/adTable';
  import { AjaxResult } from '@/api/model';
  import { List } from '@/components/Linqts';
  import { Get as GetIpn, GetDictNodes } from '@/views/wms/ipns/ipn.api';
  import { GetWareHouseTreeNodes } from '@/views/wms/warehouses/warehouse/warehouse.api';
  import { trim } from 'xe-utils';
  import { Create, Update } from './materialoutstorage.api';
  import { update } from 'lodash-es';
  import { useDrawer } from '@/components/Drawer';
  import MaterialSelectDrawer from './MaterialSelectDrawer.vue';
  import { Button } from 'ant-design-vue';
  import { FetchParams } from '@/components/Table';

  export default defineComponent({
    name: 'MaterialOutStorageDetail',
    components: {
      BasicModal,
      BasicForm,
      MaterialSelectDrawer,
    },
    props: {
      /** 表单抬头 */
      title: propTypes.string,
      /** 关闭按钮文本 */
      cancelText: propTypes.string,
      /** 确认按钮文本 */
      okText: propTypes.string,
      /** 回调方法 */
      reloadFunc: {
        type: Function as PropType<(opt?: FetchParams) => Promise<Recordable<any>[] | undefined>>,
        default: null,
      },
    },
    setup(props) {
      const { createMessage } = useMessage();
      const FormModeEntityRef = ref<FormModeEntity>(new FormModeEntity(FormModeEnum.Ok));

      const toTreeDisabled = function (data: any[]) {
        if (isArray(data) && (data as Array<any>).length > 0) {
          new List(data).ForEach((i) => {
            if (i.Level == 1 || i.Level == 2) {
              i.disabled = true;
            }
            //@ts-ignore
            if (isArray(i.Children) && (data as Array<any>).length > 0) {
              toTreeDisabled(i.Children);
            }
          });
        }
        return;
      };
      const [registerMaterialSelect, materialSelectMethods] = useDrawer();

      const schemas: FormSchema[] = [
        {
          field: 'Id',
          label: '主键',
          helpMessage: '',
          component: 'Input',
          componentProps: {
            disabled: true,
          },
        },
        {
          field: 'MaterialId',
          label: '物料编号',
          helpMessage: '',
          component: 'Input',
          show: false,
        },
        {
          field: 'IPNNo',
          label: 'IPN号',
          component: 'InputSearch',
          required: true,
          componentProps: ({ formModel, formActionType }) => {
            return {
              required: true,
              readonly: true,
              placeholder: '库存检索',
              onSearch: async (text, event) => {
                // let obj = await getObj(text);
                // formActionType.setFieldsValue(obj);
                materialSelectMethods.openDrawer(true, text);
              },
            };
          },
        },
        {
          field: 'AreaPosName',
          label: '库位',
          component: 'Input',
          required: true,
          componentProps: {
            readonly: true,
          },
        },
        {
          field: 'IPNName',
          label: '存货名称',
          component: 'Input',
          required: true,
          componentProps: {
            readonly: true,
          },
        },
        {
          field: 'IPNNum',
          label: '存货数量',
          component: 'InputNumber',
          required: true,
          componentProps: {
            readonly: true,
          },
        },
        {
          field: 'Num',
          label: '领用数量',
          component: 'InputNumber',
          required: true,
          componentProps: {
            min: 0,
          },
          rules: [
            {
              trigger: 'blur',
              validator(_, value) {
                return new Promise((resolve, reject) => {
                  if (value <= 0) {
                    reject('出库量必须大于0');
                  } else {
                    resolve();
                  }
                });
              },
            },
          ],
        },
        {
          field: 'Project',
          label: '领用项目',
          required: true,
          component: 'ApiSelect',
          componentProps: {
            api: GetDictNodes,
            params: 'project',
            resultField: 'Data',
            // use name as label
            labelField: 'CodeName',
            // use id as value
            valueField: 'CodeValue',
            immediate: true,
            optionFilterProp: 'label',
            showSearch: true,
          },
        },
        {
          field: 'UseTarget',
          label: '用途',
          required: true,
          component: 'InputTextArea',
          componentProps: {},
        },
        {
          field: 'Remark',
          label: '备注',
          required: false,
          component: 'InputTextArea',
          componentProps: {
            showCount: true,
          },
        },
        {
          label: '领用日期',
          field: 'CreatedTime',
          component: 'DatePicker',
          componentProps: {
            disabled: true,
            style: {
              width: '100%',
            },
          },
        },
      ];

      const [registerForm, formMethods] = useForm({
        /** 表单配置 */
        schemas: schemas,
        /** 扩展 form 组件，增加 label 宽度，表单内所有组件适用，可以单独在某个项覆盖或者禁用 */
        labelWidth: 120,
        /** 是否显示操作按钮(重置/提交) */
        showActionButtonGroup: false,
        baseColProps: {
          offset: 3,
          // span: 24,
          xs: 16, // <576px
          sm: 16, // ≥576px
          md: 16, // ≥768px
          lg: 16, // ≥992px
          xl: 16, // ≥1200px
          xxl: 16, // ≥1600px
          // xxxl: 24, // ≥2000px 3.0
        },
      });

      const [registerModal, modalMethods] = useModalInner(async (data) => {
        modalMethods.setModalProps({
          canFullscreen: true,
          centered: false,
          maskClosable: false,
          destroyOnClose: true,
          width: '50%',
          minHeight: 550,
          zIndex: 999,
        });
        formMethods.resetFields();
        modalMethods.changeLoading(true);
        try {
          if (data.formMode) {
            FormModeEntityRef.value = new FormModeEntity(data.formMode as FormModeEnum);
          }

          if (data.record) {
            formMethods.setFieldsValue({
              ...data.record,
            });
          }
        } finally {
          modalMethods.changeLoading(false);
        }
      });

      async function handleOk() {
        const data = await formMethods.validate();
        if (!data) return;
        openLoading();
        try {
          const formField = formMethods.getFieldsValue();
          let ajaxResult: AjaxResult<any> | null = null;
          switch (FormModeEntityRef.value.FormMode) {
            case FormModeEnum.Add:
              ajaxResult = await Create(formField);
              break;
            case FormModeEnum.Edit:
              ajaxResult = await Update(formField);
              break;
          }
          modalMethods.closeModal();
          if (props.reloadFunc && isFunction(props.reloadFunc)) {
            await props.reloadFunc();
          }
          if (ajaxResult?.Type === 200) {
            createMessage.success('成功');
          }
        } finally {
          closeLoading();
        }
      }

      function chooseMaterial(record?: Recordable) {
        if (isNullAndUnDef(record)) return;

        const material = { ...record };
        if (Reflect.has(material, 'Id')) {
          formMethods.setFieldsValue({ MaterialId: material.Id });
        }

        if (Reflect.has(material, 'IPNNo')) {
          formMethods.setFieldsValue({ IPNNo: material.IPNNo });
        }

        if (Reflect.has(material, 'IPNName')) {
          formMethods.setFieldsValue({ IPNName: material.IPNName });
        }

        if (Reflect.has(material, 'IPNNum')) {
          formMethods.setFieldsValue({ IPNNum: material.IPNNum });
          formMethods.setFieldsValue({ Num: 0 });
          formMethods.updateSchema({
            field: 'Num',
            componentProps: {
              min: 0,
              max: material.IPNNum,
            },
          });
        }

        if (
          Reflect.has(material, 'WareHouseName') &&
          Reflect.has(material, 'WareHouseAreaName') &&
          Reflect.has(material, 'WareHouseAreaPosName')
        ) {
          formMethods.setFieldsValue({
            AreaPosName: `${material.WareHouseName} >> ${material.WareHouseAreaName} >> ${material.WareHouseAreaPosName}`,
          });
        }
      }

      //#region "加载状态"
      const loadingRef = ref(false);
      /** 开启加载状态 */
      function openLoading() {
        modalMethods.changeLoading(true);
        modalMethods.setModalProps({ confirmLoading: true, cancelButtonProps: { loading: true } });
        loadingRef.value = true;
      }

      /** 关闭加载状态 */
      function closeLoading() {
        modalMethods.changeLoading(false);
        modalMethods.setModalProps({
          confirmLoading: false,
          cancelButtonProps: { loading: false },
        });
        loadingRef.value = false;
      }
      //#endregion

      return {
        registerForm,
        registerModal,
        FormModeEntityRef,
        handleOk,
        registerMaterialSelect,
        chooseMaterial,
      };
    },
  });
</script>
<style lang="less"></style>
